add api group_create/group_join

Brightcells 9 years ago
parent
commit
e184e7dd5b

+ 6 - 0
api/urls.py

@@ -3,6 +3,7 @@
3 3
 from django.conf.urls import url
4 4
 
5 5
 from account import views as account_views
6
+from group import views as group_views
6 7
 from photo import views as photo_views
7 8
 
8 9
 
@@ -13,6 +14,11 @@ urlpatterns = [
13 14
     url(r'^u/login$', account_views.user_login_api, name='user_login_api'),  # 用户登录
14 15
 ]
15 16
 
17
+urlpatterns = [
18
+    url(r'^g/create$', group_views.group_create_api, name='group_create_api'),  # 群组创建
19
+    url(r'^g/join$', group_views.group_join_api, name='group_join_api'),  # 申请加群
20
+]
21
+
16 22
 urlpatterns += [
17 23
     url(r'^uuid_init$', photo_views.uuid_init, name='uuid_init'),  # 生成唯一标识
18 24
     url(r'^uuid$', photo_views.uuid, name='uuid'),  # 获取唯一标识

+ 5 - 0
docs/errorcode

@@ -10,3 +10,8 @@
10 10
     4010 —— 参数错误
11 11
     4011 —— 摄影师不存在
12 12
     4012 —— 照片已存在
13
+
14
+
15
+3、群组信息 —— 402
16
+    4020 —— 群组不存在
17
+    4021 —— 群组已锁定

+ 0 - 0
group/__init__.py


+ 25 - 0
group/admin.py

@@ -0,0 +1,25 @@
1
+# -*- coding: utf-8 -*-
2
+
3
+from django.contrib import admin
4
+
5
+from group.models import GroupInfo, GroupUserInfo, GroupPhotoInfo
6
+
7
+
8
+class GroupInfoAdmin(admin.ModelAdmin):
9
+    list_display = ('group_id', 'group_name', 'group_desc', 'group_from', 'group_lock', 'status', 'created_at', 'updated_at')
10
+    list_filter = ('group_from', 'group_lock', 'status')
11
+
12
+
13
+class GroupUserInfoAdmin(admin.ModelAdmin):
14
+    list_display = ('group_id', 'user_id', 'nickname', 'admin', 'user_status', 'passed_at', 'refused_at', 'status', 'created_at', 'updated_at')
15
+    list_filter = ('user_status', 'status')
16
+
17
+
18
+class GroupPhotoInfoAdmin(admin.ModelAdmin):
19
+    list_display = ('group_id', 'user_id', 'nickname', 'photo_path', 'photo_thumbnail_path', 'status', 'created_at', 'updated_at')
20
+    list_filter = ('status', )
21
+
22
+
23
+admin.site.register(GroupInfo, GroupInfoAdmin)
24
+admin.site.register(GroupUserInfo, GroupUserInfoAdmin)
25
+admin.site.register(GroupPhotoInfo, GroupPhotoInfoAdmin)

+ 69 - 0
group/migrations/0001_initial.py

@@ -0,0 +1,69 @@
1
+# -*- coding: utf-8 -*-
2
+from __future__ import unicode_literals
3
+
4
+from django.db import models, migrations
5
+
6
+
7
+class Migration(migrations.Migration):
8
+
9
+    dependencies = [
10
+    ]
11
+
12
+    operations = [
13
+        migrations.CreateModel(
14
+            name='GroupInfo',
15
+            fields=[
16
+                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
17
+                ('status', models.BooleanField(default=True, help_text='\u72b6\u6001', verbose_name='status')),
18
+                ('created_at', models.DateTimeField(help_text='\u521b\u5efa\u65f6\u95f4', verbose_name='created_at', auto_now_add=True)),
19
+                ('updated_at', models.DateTimeField(help_text='\u66f4\u65b0\u65f6\u95f4', verbose_name='updated_at', auto_now=True)),
20
+                ('group_id', models.CharField(null=True, max_length=255, blank=True, help_text='\u7fa4\u7ec4\u552f\u4e00\u6807\u8bc6', unique=True, verbose_name='group_id', db_index=True)),
21
+                ('group_name', models.CharField(help_text='\u7fa4\u7ec4\u540d\u79f0', max_length=255, null=True, verbose_name='group_name', blank=True)),
22
+                ('group_desc', models.TextField(help_text='\u7fa4\u7ec4\u63cf\u8ff0', null=True, verbose_name='group_desc', blank=True)),
23
+                ('group_from', models.IntegerField(default=0, help_text='\u7fa4\u7ec4\u6765\u6e90', verbose_name='group_from', choices=[(0, 'APP \u5efa\u7fa4'), (1, 'SESSION \u5efa\u7fa4')])),
24
+                ('group_lock', models.BooleanField(default=False, help_text='\u7fa4\u7ec4\u9501\u5b9a', verbose_name='group_lock')),
25
+            ],
26
+            options={
27
+                'verbose_name': 'groupinfo',
28
+                'verbose_name_plural': 'groupinfo',
29
+            },
30
+        ),
31
+        migrations.CreateModel(
32
+            name='GroupPhotoInfo',
33
+            fields=[
34
+                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
35
+                ('status', models.BooleanField(default=True, help_text='\u72b6\u6001', verbose_name='status')),
36
+                ('created_at', models.DateTimeField(help_text='\u521b\u5efa\u65f6\u95f4', verbose_name='created_at', auto_now_add=True)),
37
+                ('updated_at', models.DateTimeField(help_text='\u66f4\u65b0\u65f6\u95f4', verbose_name='updated_at', auto_now=True)),
38
+                ('group_id', models.CharField(max_length=255, blank=True, help_text='\u7fa4\u7ec4\u552f\u4e00\u6807\u8bc6', null=True, verbose_name='group_id', db_index=True)),
39
+                ('user_id', models.CharField(help_text='\u7528\u6237\u552f\u4e00\u6807\u8bc6', max_length=255, null=True, verbose_name='user_id', blank=True)),
40
+                ('nickname', models.CharField(help_text='\u7528\u6237\u7fa4\u7ec4\u6635\u79f0', max_length=255, null=True, verbose_name='nickname', blank=True)),
41
+                ('photo_path', models.CharField(help_text='\u7167\u7247\u5b58\u653e\u8def\u5f84', max_length=255, null=True, verbose_name='photo_path', blank=True)),
42
+                ('photo_thumbnail_path', models.CharField(help_text='\u7167\u7247\u7f29\u7565\u56fe\u5b58\u653e\u8def\u5f84', max_length=255, null=True, verbose_name='photo_thumbnail_path', blank=True)),
43
+            ],
44
+            options={
45
+                'verbose_name': 'groupuserinfo',
46
+                'verbose_name_plural': 'groupuserinfo',
47
+            },
48
+        ),
49
+        migrations.CreateModel(
50
+            name='GroupUserInfo',
51
+            fields=[
52
+                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
53
+                ('status', models.BooleanField(default=True, help_text='\u72b6\u6001', verbose_name='status')),
54
+                ('created_at', models.DateTimeField(help_text='\u521b\u5efa\u65f6\u95f4', verbose_name='created_at', auto_now_add=True)),
55
+                ('updated_at', models.DateTimeField(help_text='\u66f4\u65b0\u65f6\u95f4', verbose_name='updated_at', auto_now=True)),
56
+                ('group_id', models.CharField(max_length=255, blank=True, help_text='\u7fa4\u7ec4\u552f\u4e00\u6807\u8bc6', null=True, verbose_name='group_id', db_index=True)),
57
+                ('user_id', models.CharField(help_text='\u7528\u6237\u552f\u4e00\u6807\u8bc6', max_length=255, null=True, verbose_name='user_id', blank=True)),
58
+                ('nickname', models.CharField(help_text='\u7528\u6237\u7fa4\u7ec4\u6635\u79f0', max_length=255, null=True, verbose_name='nickname', blank=True)),
59
+                ('admin', models.BooleanField(default=False, help_text='\u7fa4\u7ec4\u7ba1\u7406\u5458', verbose_name='admin')),
60
+                ('user_status', models.IntegerField(default=0, verbose_name='user_status', choices=[(0, '\u7533\u8bf7\u4e2d'), (1, '\u5df2\u901a\u8fc7'), (2, '\u5df2\u62d2\u7edd')])),
61
+                ('passed_at', models.DateTimeField(help_text='\u901a\u8fc7\u65f6\u95f4', null=True, verbose_name='passed_at', blank=True)),
62
+                ('refused_at', models.DateTimeField(help_text='\u62d2\u7edd\u65f6\u95f4', null=True, verbose_name='refused_at', blank=True)),
63
+            ],
64
+            options={
65
+                'verbose_name': 'groupuserinfo',
66
+                'verbose_name_plural': 'groupuserinfo',
67
+            },
68
+        ),
69
+    ]

+ 19 - 0
group/migrations/0002_groupinfo_session_id.py

@@ -0,0 +1,19 @@
1
+# -*- coding: utf-8 -*-
2
+from __future__ import unicode_literals
3
+
4
+from django.db import models, migrations
5
+
6
+
7
+class Migration(migrations.Migration):
8
+
9
+    dependencies = [
10
+        ('group', '0001_initial'),
11
+    ]
12
+
13
+    operations = [
14
+        migrations.AddField(
15
+            model_name='groupinfo',
16
+            name='session_id',
17
+            field=models.CharField(max_length=255, blank=True, help_text='\u7167\u7247\u7ec4\u552f\u4e00\u6807\u8bc6', null=True, verbose_name='session_id', db_index=True),
18
+        ),
19
+    ]

+ 0 - 0
group/migrations/__init__.py


+ 101 - 0
group/models.py

@@ -0,0 +1,101 @@
1
+# -*- coding: utf-8 -*-
2
+
3
+from django.conf import settings
4
+from django.db import models
5
+from django.utils.translation import ugettext_lazy as _
6
+
7
+from pai2.basemodels import CreateUpdateMixin
8
+
9
+
10
+class GroupInfo(CreateUpdateMixin):
11
+    APP_GROUP = 0
12
+    SESSION_GROUP = 1
13
+
14
+    GROUP_FROM = (
15
+        (APP_GROUP, u'APP 建群'),
16
+        (SESSION_GROUP, u'SESSION 建群'),
17
+    )
18
+
19
+    group_id = models.CharField(_(u'group_id'), max_length=255, blank=True, null=True, help_text=u'群组唯一标识', db_index=True, unique=True)
20
+    group_name = models.CharField(_(u'group_name'), max_length=255, blank=True, null=True, help_text=u'群组名称')
21
+    group_desc = models.TextField(_(u'group_desc'), blank=True, null=True, help_text=u'群组描述')
22
+    group_from = models.IntegerField(_(u'group_from'), choices=GROUP_FROM, default=APP_GROUP, help_text=u'群组来源')
23
+    session_id = models.CharField(_(u'session_id'), max_length=255, blank=True, null=True, help_text=u'照片组唯一标识', db_index=True)
24
+    group_lock = models.BooleanField(_(u'group_lock'), default=False, help_text=u'群组锁定')
25
+
26
+    class Meta:
27
+        verbose_name = _(u'groupinfo')
28
+        verbose_name_plural = _(u'groupinfo')
29
+
30
+    def __unicode__(self):
31
+        return unicode(self.group_id)
32
+
33
+    @property
34
+    def users(self):
35
+        all_users = GroupUserInfo.objects.filter(group_id=self.group_id)
36
+        applying_users = all_users.filter(user_status=GroupUserInfo.APPLYING)
37
+        passed_users = all_users.filter(user_status=GroupUserInfo.PASSED)
38
+        return {
39
+            'applying_count': applying_users.count(),
40
+            'passed_count': passed_users.count(),
41
+            'applying': [applying.user_info for applying in applying_users],
42
+            'passed': [passed.user_info for passed in passed_users],
43
+        }
44
+
45
+
46
+class GroupUserInfo(CreateUpdateMixin):
47
+    APPLYING = 0
48
+    PASSED = 1
49
+    REFUSED = 2
50
+
51
+    USER_STATUS = (
52
+        (APPLYING, u'申请中'),
53
+        (PASSED, u'已通过'),
54
+        (REFUSED, u'已拒绝'),
55
+    )
56
+
57
+    group_id = models.CharField(_(u'group_id'), max_length=255, blank=True, null=True, help_text=u'群组唯一标识', db_index=True)
58
+    user_id = models.CharField(_(u'user_id'), max_length=255, blank=True, null=True, help_text=u'用户唯一标识')
59
+    nickname = models.CharField(_(u'nickname'), max_length=255, blank=True, null=True, help_text=u'用户群组昵称')
60
+    admin = models.BooleanField(_(u'admin'), default=False, help_text=u'群组管理员')
61
+    user_status = models.IntegerField(_(u'user_status'), choices=USER_STATUS, default=APPLYING)
62
+    passed_at = models.DateTimeField(_(u'passed_at'), blank=True, null=True, help_text=_(u'通过时间'))
63
+    refused_at = models.DateTimeField(_(u'refused_at'), blank=True, null=True, help_text=_(u'拒绝时间'))
64
+
65
+    class Meta:
66
+        verbose_name = _(u'groupuserinfo')
67
+        verbose_name_plural = _(u'groupuserinfo')
68
+
69
+    def __unicode__(self):
70
+        return unicode(self.pk)
71
+
72
+    @property
73
+    def user_info(self):
74
+        return {
75
+            'user_id': self.user_id,
76
+            'nickname': self.nickname,
77
+            'admin': self.admin,
78
+        }
79
+
80
+
81
+class GroupPhotoInfo(CreateUpdateMixin):
82
+    group_id = models.CharField(_(u'group_id'), max_length=255, blank=True, null=True, help_text=u'群组唯一标识', db_index=True)
83
+    user_id = models.CharField(_(u'user_id'), max_length=255, blank=True, null=True, help_text=u'用户唯一标识')
84
+    nickname = models.CharField(_(u'nickname'), max_length=255, blank=True, null=True, help_text=u'用户群组昵称')
85
+    photo_path = models.CharField(_(u'photo_path'), max_length=255, blank=True, null=True, help_text=u'照片存放路径')
86
+    photo_thumbnail_path = models.CharField(_(u'photo_thumbnail_path'), max_length=255, blank=True, null=True, help_text=u'照片缩略图存放路径')
87
+
88
+    class Meta:
89
+        verbose_name = _(u'groupuserinfo')
90
+        verbose_name_plural = _(u'groupuserinfo')
91
+
92
+    def __unicode__(self):
93
+        return unicode(self.pk)
94
+
95
+    @property
96
+    def photo_url(self):
97
+        return u'{0}/{1}'.format(settings.IMG_DOMAIN, self.photo_path) if self.photo_path else ''
98
+
99
+    @property
100
+    def photo_thumbnail_url(self):
101
+        return u'{0}/{1}'.format(settings.IMG_DOMAIN, self.photo_thumbnail_path) if self.photo_thumbnail_path else ''

+ 23 - 0
group/serializers.py

@@ -0,0 +1,23 @@
1
+# -*- coding: utf-8 -*-
2
+
3
+from rest_framework import serializers
4
+
5
+from group.models import GroupInfo, GroupUserInfo, GroupPhotoInfo
6
+
7
+
8
+class GroupInfoSerializer(serializers.HyperlinkedModelSerializer):
9
+    class Meta:
10
+        model = GroupInfo
11
+        fields = ('group_id', 'group_name', 'group_desc', 'group_from', 'group_lock', 'status', 'created_at', 'updated_at')
12
+
13
+
14
+class GroupUserInfoSerializer(serializers.HyperlinkedModelSerializer):
15
+    class Meta:
16
+        model = GroupUserInfo
17
+        fields = ('group_id', 'user_id', 'nickname', 'admin', 'user_status', 'passed_at', 'refused_at', 'status', 'created_at', 'updated_at')
18
+
19
+
20
+class GroupPhotoInfoSerializer(serializers.HyperlinkedModelSerializer):
21
+    class Meta:
22
+        model = GroupPhotoInfo
23
+        fields = ('group_id', 'user_id', 'nickname', 'photo_path', 'photo_thumbnail_path', 'status', 'created_at', 'updated_at')

+ 3 - 0
group/tests.py

@@ -0,0 +1,3 @@
1
+from django.test import TestCase
2
+
3
+# Create your tests here.

+ 106 - 0
group/views.py

@@ -0,0 +1,106 @@
1
+# -*- coding: utf-8 -*-
2
+
3
+from django.db import transaction
4
+from django.http import JsonResponse
5
+
6
+from rest_framework import viewsets
7
+
8
+from account.models import UserInfo
9
+from group.models import GroupInfo, GroupUserInfo, GroupPhotoInfo
10
+from group.serializers import GroupInfoSerializer, GroupUserInfoSerializer, GroupPhotoInfoSerializer
11
+
12
+from utils.ip_utils import ip_addr
13
+
14
+from curtail_uuid import CurtailUUID
15
+from TimeConvert import TimeConvert as tc
16
+
17
+
18
+@transaction.atomic
19
+def group_create_api(request):
20
+    user_id = request.POST.get('user_id', '')
21
+
22
+    try:
23
+        user = UserInfo.objects.get(user_id=user_id)
24
+    except UserInfo.DoesNotExist:
25
+        return JsonResponse({
26
+            'status': 4011,
27
+            'message': u'用户不存在',
28
+        })
29
+
30
+    group_id = CurtailUUID.uuid(GroupInfo, 'group_id')
31
+    group = GroupInfo.objects.create(
32
+        group_id=group_id,
33
+        group_from=GroupInfo.APP_GROUP,
34
+    )
35
+    GroupUserInfo.objects.create(
36
+        group_id=group_id,
37
+        user_id=user_id,
38
+        nickname=user.username,
39
+        admin=True,
40
+        user_status=GroupUserInfo.PASSED,
41
+        passed_at=tc.utc_datetime(),
42
+    )
43
+
44
+    return JsonResponse({
45
+        'status': 200,
46
+        'message': u'群组创建成功',
47
+        'data': {
48
+            'group_id': group_id,
49
+            'users': group.users
50
+        },
51
+    })
52
+
53
+
54
+def group_join_api(request):
55
+    group_id = request.POST.get('group_id', '')
56
+    user_id = request.POST.get('user_id', '')
57
+    nickname = request.POST.get('nickname', '')
58
+
59
+    try:
60
+        user = UserInfo.objects.get(user_id=user_id)
61
+    except UserInfo.DoesNotExist:
62
+        return JsonResponse({
63
+            'status': 4011,
64
+            'message': u'用户不存在',
65
+        })
66
+
67
+    try:
68
+        group = GroupInfo.objects.get(group_id=group_id)
69
+    except GroupInfo.DoesNotExist:
70
+        return JsonResponse({
71
+            'status': 4020,
72
+            'message': u'群组不存在',
73
+        })
74
+    if group.group_lock:
75
+        return JsonResponse({
76
+            'status': 4021,
77
+            'message': u'群组已锁定',
78
+        })
79
+
80
+    GroupUserInfo.objects.create(
81
+        group_id=group_id,
82
+        user_id=user_id,
83
+        nickname=nickname or user.username,
84
+        admin=False,
85
+        user_status=GroupUserInfo.APPLYING,
86
+    )
87
+
88
+    return JsonResponse({
89
+        'status': 200,
90
+        'message': u'申请已提交',
91
+    })
92
+
93
+
94
+class GroupInfoViewSet(viewsets.ModelViewSet):
95
+    queryset = GroupInfo.objects.all().order_by('-created_at')
96
+    serializer_class = GroupInfoSerializer
97
+
98
+
99
+class GroupUserInfoViewSet(viewsets.ModelViewSet):
100
+    queryset = GroupUserInfo.objects.all().order_by('-created_at')
101
+    serializer_class = GroupUserInfoSerializer
102
+
103
+
104
+class GroupPhotoInfoViewSet(viewsets.ModelViewSet):
105
+    queryset = GroupPhotoInfo.objects.all().order_by('-created_at')
106
+    serializer_class = GroupPhotoInfoSerializer

+ 1 - 0
pai2/settings.py

@@ -43,6 +43,7 @@ INSTALLED_APPS = (
43 43
     'rest_framework',
44 44
     'api',
45 45
     'account',
46
+    'group',
46 47
     'photo',
47 48
 )
48 49
 

+ 7 - 0
pai2/urls.py

@@ -22,13 +22,20 @@ from django.contrib import admin
22 22
 
23 23
 from rest_framework import routers
24 24
 from account import views as account_views
25
+from group import views as group_views
25 26
 from photo import views as photo_views
26 27
 
27 28
 router = routers.DefaultRouter()
28 29
 # router.register(r'users', account_views.UserViewSet)
29 30
 # router.register(r'groups', account_views.GroupViewSet)
31
+
30 32
 router.register(r'lensmans', account_views.LensmanInfoViewSet)
31 33
 router.register(r'users', account_views.UserInfoViewSet)
34
+
35
+router.register(r'groups', group_views.GroupInfoViewSet)
36
+router.register(r'group_users', group_views.GroupUserInfoViewSet)
37
+router.register(r'group_photos', group_views.GroupPhotoInfoViewSet)
38
+
32 39
 router.register(r'photos', photo_views.PhotoInfoViewSet)
33 40
 
34 41
 urlpatterns = [